package ui;

import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

import core.City;
import core.QuestionLog;
import core.UserMgmt;
import db.DB_Abstract;
import db.DB_SQL;

public class MainWindow {
	
	// Constants
	public static final String TITLE = "Pin It!";
	public static final String INSTRUCTIONS = 
			"1) Create a user at the 'Settings' tab or login if you already have one.\n" +
			"2) Create a group or join an existing group, everybody can join all groups.\n" +
			"3) Click 'Play' or go to 'Play' tab, 'Generate New Question' will do what it says.\n" +
			"4) The answer is some place you have to find on the map... PIN IT!\n" +
			"5) You will then see the right answer and get the score you deserve.\n" +
			"6) Your highest score will be saved in the group every time a game ends.\n" +
			"you can play as many games as you want to try and beat everyones score.\n" + 
			"Go Pin It!";
	
	// Members
	public static Display display;
	public static DB_Abstract myDB;
	public static Thread stpwtchThread;
	
	// SWT Members
	public static TabFolder tabs; 
	public static List listLogs;
	public static TabItem tbtmPlay;
	public static Browser browser;
	public static Label lblCountdown;
	public static Text txtQuestion;
	public static Label lblPlayGroup; 
	public static Text txtLoginUserName;
	public static Text txtLoginUserPass;
	public static Text txtNewUserName;
	public static Text txtNewUserPass;
	public static Group grpGroupsBoard;
	public static Table tblGroupsBoard;
	public static Combo cmbJoinGroup;
	public static Text txtNewGroupName;
	public static Text txtNewGroupQuestions;
	public static Combo cmbNewGroupCountry;
	public static Combo cmbNewGroupContinent;
	public static Button rbtn1ByCountry;
	public static Button rbtn2ByContinent;
	public static Button rbtn3AllCities;
	public static MenuItem mntmLogout;
	public static Group grpJoinGroup;
	public static Group grpCreateNewGroup;
	public static Button btnGenerateQuestion;
	public static Button btnPinIt;
	public static Group grpLogin; 
	public static Group grpNewUser;
	public static Button btnLogin; 
	public static Button btnCreateUser;
	public static Button btnJoinGroup; 
	public static Button btnCreateGroup;
	public static Table tblGrpHighScore;
	public static Group grpPlayCurrScore;
	public static Label lblPlayCurrScore;
	public static Composite editTabLayout;
	public static Group grpEditNew;
	public static Group grpEditEdit;
	public static Label lblName_1;
	public static Label lblCountry;
	public static Text txtAddCityName;
	public static Combo cmbAddCityCountry;
	public static Button btnAddCity;
	public static Browser browserEdit;
	public static Combo cmbEditCity;
	public static Label lblSelectCity;
	public static Button btnEditCity;
	public static Label lblYouCanEdit;
	public static Button btnDeleteGroup;
	public static Button btnPlay;
	public static Group grpGroupInfo;
	public static Label lblGroupInfoName;
	public static Label lblGroupInfoType;
	public static Label lblGroupInfoQuestions;
	public static Text txtGroupInfoName;
	public static Text txtGroupInfoType;
	public static Text txtGroupInfoQuestions;
	public static Group grpPlayQuestionsLeft;
	public static Label lblQuestionsLeft;
	public static TabItem tbtmStatistics;
	public static Composite composite;
	public static Label lblStatisticsUser;
	public static Table tblStatistics;
	public static TableColumn tblclmnAskedAbout;
	public static TableColumn tblclmnInGroup;
	public static TableColumn tblclmnTime;
	public static TableColumn tblclmnScore_1;
	public static TableColumn tblclmnWhen;
	public static Button btnUpdateStatistics;
	public static Button btnWhereIsIt;
	public static TabItem tbtmUpdateDb;
	public static Composite updateTabLayout;
	public static Group group_1;
	public static Label lblWarning;
	public static Button btnOverride;
	public static Button btnUpdateDB;
	public static Label lblContinentsCountries;
	public static Label lblCitiesFilePath;
	public static Label lblPinItFolder;
	public static Text txtContinentsPath;
	public static Text txtCitiesPath;
	public static Text txtWorkingFolder;
	public static Button btnLeaveGroup;
	public static Button btnLogout;
	
	
	/**
	 * MAIN
	 * @param args
	 */
	public static void main(String[] args) {
		display = Display.getDefault();
		Shell shell = new Shell(display);
		
		//DB connection is critical, quit if unsuccessful
		myDB = new DB_SQL();
		if (myDB.connect() == 0) {
			return;
		}
		
		createContents(shell); //long and boring method at end of this file
		
		//stuff to happen at startup
		shell.layout(); //important 1
		shell.pack();	//important 2	
		refreshUI();
		UserMgmt.populateGroupComboBox();
		UserMgmt.populateCountryComboBox();
		UserMgmt.populateContinentComboBox();
		try { //fill paths in 'Update DB' tab
			String workingFolder = MainWindow.class.getProtectionDomain().getCodeSource().getLocation().getPath();
			if (!workingFolder.equals("")) {
				//trim first char if it's '/' on windows
				if (workingFolder.charAt(0) == '/' && File.separatorChar == '\\') {
					workingFolder = workingFolder.substring(1);
					workingFolder = workingFolder.replaceAll("\\/", "\\\\");
				}
				
				//trim file from path
				workingFolder = workingFolder.substring(0, workingFolder.lastIndexOf(File.separatorChar) + 1);
				
				txtContinentsPath.setText(workingFolder + "GeoLite2-Country-Locations.csv");
				txtCitiesPath.setText(workingFolder + "worldcitiespop.txt");
				txtWorkingFolder.setText(workingFolder.substring(0, workingFolder.length() - 1)); // trim last char
			}
		} catch (Exception e) {
			//catch all exceptions and do nothing - it's only cosmetic and extremely unimportant
		}
		
		openShell(shell);
		//only end of life code from here
		myDB.closeConnection();
	}
	
	
	/**
	 * opens the main window shell
	 * @param shell
	 */
	private static void openShell(Shell shell) {
		shell.open();
		
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}
	
	
	// MORE METHODS
	//*************
	
	
	/**
	 * show currQuestion to the screen
	 */
	public static void showCurrQuestion() {
		//first letter to upper case 
		//Separate to words
		String[] cityArr = UserMgmt.currUser.getCurrQuestion().cityName.split(" ");
		StringBuffer cityName = new StringBuffer();
		for( int i = 0; i < cityArr.length; i++){
			cityArr[i] = Character.toUpperCase(cityArr[i].charAt(0)) + cityArr[i].substring(1);
			cityName.append(cityArr[i] + " ");
		}
		
		txtQuestion.setText("Where is " + cityName.toString() + "? Pin it on the map");
		
	}
	
	
	/**
	 * checks if currUser finished game
	 * @return
	 */
	private static boolean isGameFinished() {
		return UserMgmt.currUser.getQuestionsAsked() == UserMgmt.currUser.getCurrGroup().getNumOfQuestions();
	}
	
	
	/**
	 * initiate game parameters
	 */
	private static void initUserGameParams() {
		UserMgmt.currUser.setCurrScore(0);
		UserMgmt.currUser.setQuestionsAsked(0);
		//retrieve highscore
		for (core.Group g : UserMgmt.currUserGroups) {
			if (g.getName().equals(UserMgmt.currUser.getCurrGroup().getName())) {
				UserMgmt.currUser.setScore(g.getScore());
			}
		}
		//UserMgmt.currUser.setScore(UserMgmt.currUserGroups.get(UserMgmt.currUserGroups.indexOf(UserMgmt.currUser.getCurrGroup())).getScore());
		//UserMgmt.currUser.setScore(UserMgmt.currUser.getCurrGroup().getScore());
	}
	
	
	/**
	 * set UI elements enabled-disabled according to situation
	 */
	public static void refreshUI() {
		
		//clear login and create user forms
		txtLoginUserName.setText("");
		txtLoginUserPass.setText("");
		txtNewUserName.setText("");
		txtNewUserPass.setText("");
		btnLeaveGroup.setEnabled(false);
		btnDeleteGroup.setEnabled(false);
		btnUpdateDB.setEnabled(false);
		
		//set buttons enabled\disabled according to state
		if (UserMgmt.currUser == null || UserMgmt.currUser.getName().equals("admin") ) {
		// no user or admin user logged-in
			
			//delete some labels
			lblPlayCurrScore.setText("");
			lblPlayGroup.setText("");
			txtGroupInfoName.setText("");
			txtGroupInfoQuestions.setText("");
			txtGroupInfoType.setText("");
			
			//set these disabled
			mntmLogout.setEnabled(false);
			btnLogout.setEnabled(false);
			btnPlay.setEnabled(false);
			
			btnJoinGroup.setEnabled(false);
			btnCreateGroup.setEnabled(false);
			grpJoinGroup.setEnabled(false);
			grpCreateNewGroup.setEnabled(false);
			
			btnGenerateQuestion.setEnabled(false);
			btnPinIt.setEnabled(false);
			
			btnAddCity.setEnabled(false);
			grpEditNew.setEnabled(false);
			btnEditCity.setEnabled(false);
			btnWhereIsIt.setEnabled(false);
			grpEditEdit.setEnabled(false);
						
			//set these enabled
			btnLogin.setEnabled(true);
			btnCreateUser.setEnabled(true);
			grpLogin.setEnabled(true);
			grpNewUser.setEnabled(true);
						
		} else {
		// a user is logged-in

			//set these disabled
			btnLogin.setEnabled(false);
			btnCreateUser.setEnabled(false);
			grpLogin.setEnabled(false);
			grpNewUser.setEnabled(false);			
			
			btnPinIt.setEnabled(false);
			btnGenerateQuestion.setEnabled(false);
			
			//set these enabled
			mntmLogout.setEnabled(true);
			btnLogout.setEnabled(true);
			
			btnJoinGroup.setEnabled(true);
			btnCreateGroup.setEnabled(true);
			grpJoinGroup.setEnabled(true);
			grpCreateNewGroup.setEnabled(true);
			
			btnAddCity.setEnabled(true);
			grpEditNew.setEnabled(true);
			btnEditCity.setEnabled(true);
			btnWhereIsIt.setEnabled(true);
			grpEditEdit.setEnabled(true);
			
			if (UserMgmt.currUser.getCurrGroup() != null) {
			//user joined a group
				// enable this
				btnLeaveGroup.setEnabled(true);
				btnGenerateQuestion.setEnabled(true);
				btnPlay.setEnabled(true);
			} else {
				//user didn't join a group
				lblPlayCurrScore.setText("");
				lblPlayGroup.setText("");
				btnPlay.setEnabled(false);
			}
		}
		
		//update high score tables
		UserMgmt.updateGroupsTable();
		UserMgmt.updateGrpHighScoreTable();
	}
	
	
	/**
	 * PinIt!
	 * invoked by thread checking for pins to map
	 */
	public static void PinIt() {
		
		//disable user pin in map
		browser.evaluate("canMap = false");
		
    	// get user coordinates from map
		double lat = ((Double) browser.evaluate("return usrMarker.position.lat();")).doubleValue();
        double lng = ((Double) browser.evaluate("return usrMarker.position.lng();")).doubleValue();
		
		//enable generateNewQuestion button
		btnGenerateQuestion.setEnabled(true);

        //calc the score for current question (appends distance to log)
        int currQuesScore = UserMgmt.calcQuestionScore(lat, lng, Integer.parseInt(lblCountdown.getText()));
        Logs.append("Time Penalty: " + lblCountdown.getText() + " Points");		        		        
        //update user currScore and currScore label
        UserMgmt.currUser.addToCurrScore(currQuesScore);
        lblPlayCurrScore.setText(((Integer)UserMgmt.currUser.getCurrScore()).toString());
        //show the user it's score and the exact point
        Logs.append("Score: " + currQuesScore);
        
        //add question to DB log
        myDB.addNewQuestion(UserMgmt.currUser.getID(),UserMgmt.currUser.getCurrGroup().getId(), UserMgmt.currUser.getCurrQuestion().getCityId(),currQuesScore,  Integer.parseInt(lblCountdown.getText()),  new java.util.Date().getTime());
       
        //check if user finished a game
        if (isGameFinished()) {
			Logs.append("Congratulations ! You completed a Game in Group "+UserMgmt.currUser.getCurrGroup().getName()+
					" With the Score " + UserMgmt.currUser.getCurrScore());
			if(UserMgmt.currUser.getCurrScore() > UserMgmt.currUser.getScore()){ //new score bigger than high Score
				Logs.append("Well Done ! You achived a new high score !"); 
				UserMgmt.currUser.setScore(UserMgmt.currUser.getCurrScore());
				//update DB with new result
				myDB.modifyUserInGroup(UserMgmt.currUser.getID(), UserMgmt.currUser.getCurrGroup().getId(), UserMgmt.currUser.getScore());
				refreshUI();
			}
			
			// show OK dialog with game end message
			MessageBox messageBox = new MessageBox(MainWindow.display.getShells()[0], SWT.OK);
	        messageBox.setText("Game Finished");
	        messageBox.setMessage("Congratulations! You have just finished a game!\nyou can continue playing to get a higher score.");
	        messageBox.open();
		}
        
      //enable buttons
      btnJoinGroup.setEnabled(true);
      btnCreateGroup.setEnabled(true);
	}
	
	
	/**
	 * 'generate new question' button pressed
	 */
	private static void GenerateNewQuestion() {
		
		//check if user finished a game
        if(isGameFinished()){
        	//start a new game on the same group
        	initUserGameParams();
        	//load new questions to current group (game)
        	UserMgmt.currUser.getCurrGroup().loadQuestions();
        	
        }
        //anyway:
        //get next question from group and updates currUser.currQuestion
		City newQuestion = UserMgmt.currUser.getCurrGroup().getNextQuestion();
		if(newQuestion == null ){ 
			// Error, no question to ask
			Logs.append("No Questions Left For Current Game.");
			
		}else{//got new question
			UserMgmt.currUser.setCurrQuestion(newQuestion);
			
			 //show Question to the screen
			 showCurrQuestion();
			
		}
		
		//DecimalFormat decFormat = new DecimalFormat("#.######");
		
		// disable this button
		btnGenerateQuestion.setEnabled(false);
		//start stopWatchThread
		stpwtchThread = new Thread(new StopwatchThread());
	    stpwtchThread.start();
	    //set map stuff
	    if ((boolean) browser.evaluate("return clickDetected")) {
	    	//don't try to clear markers on first time, it will crash
	    	browser.evaluate("return clearMarkers()");
	    }
	    browser.evaluate("canMap = true");
	    browser.evaluate("clickDetected = false");
	    Double trueLat = (double) UserMgmt.currUser.getCurrQuestion().getLatitude();
	    Double trueLng = (double) UserMgmt.currUser.getCurrQuestion().getLongtitude();
	    browser.evaluate("trueLatlng = new google.maps.LatLng("+ trueLat +", "+ trueLng +")");
	    //Logs.append("trueLatlng = new google.maps.LatLng("+ decFormat.format(trueLat) +", "+ decFormat.format(trueLng) +")");
	    
	    float Min = -2f;
	    float Max = 2f;
	    Double randLat = trueLat + (Min + (int)(Math.random() * ((Max - Min) + 1)));
	    Double randLng = trueLng + (Min + (int)(Math.random() * ((Max - Min) + 1)));
	    //Double randLng = 
	    browser.evaluate("map.setZoom(6)");
	    browser.evaluate("center = new google.maps.LatLng("+ randLat +", "+ randLng +")");
	    browser.evaluate("map.panTo(center)");
	    
		//update questions left label
		lblQuestionsLeft.setText(Integer.toString(UserMgmt.currUser.getCurrGroup().getNumberOfQuestionsLeft()));
		
		//disable buttons
		btnJoinGroup.setEnabled(false);
		btnCreateGroup.setEnabled(false);
	}
	
	
	/**
	 * 'select group' button pressed
	 */
	public static void joinGroup() {
		int groupIndex;
		if((groupIndex = cmbJoinGroup.getSelectionIndex()) != -1) { // user selected a group
			//set selected group as current group
			UserMgmt.currUser.setCurrGroup(UserMgmt.groupList.get(groupIndex));
			// show a message and selected group in play tab
			String selectedGroupName = UserMgmt.currUser.getCurrGroup().getName();
			lblPlayGroup.setText(selectedGroupName);
			Logs.append(Logs.LOG_GROUP_SELECTED + selectedGroupName);
			
			// add user to group only if not already
			boolean alreadyInGroup = false;
			for (core.Group g : UserMgmt.currUserGroups) {
				if (g.getId() == UserMgmt.currUser.getCurrGroup().getId()) {
					alreadyInGroup = true;
					break;
				}
			}
			if (!alreadyInGroup) {
				myDB.addUserToGroup(UserMgmt.currUser, UserMgmt.currUser.getCurrGroup());
			}
			// init game parameters
			initUserGameParams();
			// load questions into currGroup, for current game
			UserMgmt.currUser.getCurrGroup().loadQuestions();
			
			txtGroupInfoName.setText(UserMgmt.currUser.getCurrGroup().getName());
			txtGroupInfoQuestions.setText(Integer.toString(UserMgmt.currUser.getCurrGroup().getNumOfQuestions()));
			
			int groupCountryID = UserMgmt.currUser.getCurrGroup().getCountryID();
			int groupContinentID = UserMgmt.currUser.getCurrGroup().getContID();
			
			if (groupCountryID > 0) {
				//type cities is country
				String countryName = myDB.getCountry(groupCountryID).getCountryName();
				txtGroupInfoType.setText("Cities in country " + countryName + ".");
			} else {
				if (groupContinentID > 0) {
					//type cities in continent
					String continentName = myDB.getContinent(groupContinentID).getContinentName();
					txtGroupInfoType.setText("Cities in continent " + continentName + ".");
				} else {
					//type all cities
					txtGroupInfoType.setText("All Cities.");
				}
			}
			
			refreshUI();
			
		} else {
			Logs.append("Select a group please.");
		}
	}
	
	
	/**
	 * addCityBtnHandler
	 */
	private static void addCityBtnHandler() {
		//get name from UI
		String newCityName = txtAddCityName.getText();
		
		//get countryID from UI
		int newCityCountrySelectionIdx = -1;
		int newCityCountryID = -1;
		if (!cmbAddCityCountry.getText().equals("")) {
			newCityCountrySelectionIdx = cmbAddCityCountry.getSelectionIndex();
			newCityCountryID = UserMgmt.countriesList.get(newCityCountrySelectionIdx).getCountryId();
		}
		
		//check clickDetected in map
		if ((boolean) browserEdit.evaluate("return clickDetected")) {
			//get lon lat from UI
			double newCityLat = ((Double) browserEdit.evaluate("return usrMarker.position.lat();")).doubleValue();
	        double newCityLng = ((Double) browserEdit.evaluate("return usrMarker.position.lng();")).doubleValue();
	        //add to db after sanity checks
			if (!newCityName.equals("") && newCityCountryID != -1) {
				myDB.addNewCity(new City(newCityName, (float)newCityLat, (float)newCityLng, newCityCountryID, -1));
				Logs.append("New City added to DB: " + newCityName + ", Coordinates: Lat " + newCityLat + ", Long " + newCityLng);
			} else {
				Logs.append("Add city - input error.");
			}
		} else {
			Logs.append("You must pin a point on the map.");
		}
	}
	
	
	/**
	 * editCityBtnHandler
	 */
	public static void editCityBtnHandler() {
		//get city name from UI
		String editCityName = cmbEditCity.getText();
		
		int editCityID = -1;
		int editCitySelectionIdx = -1;
		if((editCitySelectionIdx = cmbEditCity.getSelectionIndex()) != -1) {	
			editCityID = UserMgmt.userQuestions.get(editCitySelectionIdx).getCityId();
		}
		
		//check clickDetected in map
		if ((boolean) browserEdit.evaluate("return clickDetected")) {
			//get lon lat from UI
			double editCityLat = ((Double) browserEdit.evaluate("return usrMarker.position.lat();")).doubleValue();
	        double editCityLng = ((Double) browserEdit.evaluate("return usrMarker.position.lng();")).doubleValue();
	        //edit db after sanity checks
			if (editCityID != -1) {
				myDB.modifyCityLat((float)editCityLat, editCityID);
				myDB.modifyCityLong((float)editCityLng, editCityID);
				Logs.append("City edited in DB: " + editCityName + ", New Coordinates: Lat " + editCityLat + ", Long " + editCityLng);
			} else {
				Logs.append("Edit city - input error.");
			}
		} else {
			Logs.append("You must pin a point on the map.");
		}
	}
	
	
	/**
	 * creates main window contents
	 * @param shell
	 */
	private static void createContents(Shell shell) {
		shell.setMinimumSize(new Point(800, 600));
		shell.setText(TITLE);
		FillLayout fl_shell = new FillLayout();
		fl_shell.type = SWT.VERTICAL;
		shell.setLayout(fl_shell);
		
		// *** Menu ***
		Menu menu = new Menu(shell, SWT.BAR);
		shell.setMenuBar(menu);
		
		MenuItem menuItem = new MenuItem(menu, SWT.CASCADE);
		menuItem.setText("Menu");
		
		Menu menuMenu = new Menu(menuItem);
		menuItem.setMenu(menuMenu);
		
		mntmLogout = new MenuItem(menuMenu, SWT.NONE);
		mntmLogout.setText("Logout");
		mntmLogout.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				UserMgmt.logout();
				refreshUI();
			}
		});
		
		new MenuItem(menuMenu, SWT.SEPARATOR);
		
		MenuItem mntmExit = new MenuItem(menuMenu, SWT.NONE);
		mntmExit.setText("Exit");
		
		MenuItem mntmInstructions = new MenuItem(menu, SWT.NONE);
		mntmInstructions.setText("How To Play");
		mntmInstructions.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
			    // show OK dialog with game end message
				MessageBox messageBox = new MessageBox(display.getShells()[0], SWT.OK);
		        messageBox.setText("Instructions");
		        messageBox.setMessage(INSTRUCTIONS);
		        messageBox.open();
			}
		});
		mntmExit.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				display.getShells()[0].dispose();
			}
		});
		
	    // Base sashForm layout: contains tab-folders and logs
		SashForm sashBase = new SashForm(shell, SWT.VERTICAL);
		tabs = new TabFolder(sashBase, SWT.NONE);
		
		// *** Users Tab ***
		TabItem tbtmUsers = new TabItem(tabs, SWT.NONE);
		tbtmUsers.setText("Settings");
		
		Composite usersTabLayout = new Composite(tabs, SWT.NONE);
		tbtmUsers.setControl(usersTabLayout);
		usersTabLayout.setLayout(new GridLayout(3, false));
		
		// *** Login ***
		grpLogin = new Group(usersTabLayout, SWT.NONE);
		grpLogin.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		grpLogin.setText("Login");
		grpLogin.setLayout(new GridLayout(2, false));
		
		Label lblLoginUserName = new Label(grpLogin, SWT.NONE);
		lblLoginUserName.setText("User Name:");
		
		txtLoginUserName = new Text(grpLogin, SWT.BORDER);
		txtLoginUserName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		txtLoginUserName.setTextLimit(20);
		
		Label lblLoginUserPass = new Label(grpLogin, SWT.NONE);
		lblLoginUserPass.setText("Password:");
		
		txtLoginUserPass = new Text(grpLogin, SWT.BORDER | SWT.PASSWORD);
		txtLoginUserPass.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		txtLoginUserPass.setTextLimit(20);
		
		btnLogin = new Button(grpLogin, SWT.CENTER);
		btnLogin.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnLogin.setText("Login");
		btnLogin.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				UserMgmt.login();
				refreshUI();
				
				//handle admin - can delete groups and update db but can't do anything else
				if (UserMgmt.currUser != null && UserMgmt.currUser.getName().equals("admin")) {
					
					grpJoinGroup.setEnabled(true);
					MainWindow.btnDeleteGroup.setEnabled(true);
					
					mntmLogout.setEnabled(true);
					btnLogout.setEnabled(true);
					
					MainWindow.btnUpdateDB.setEnabled(true);
				}
			}
		});
		
		// *** ScoreBoard ***
		grpGroupsBoard = new Group(usersTabLayout, SWT.NONE);
		RowLayout rl_grpGroupsBoard = new RowLayout(SWT.HORIZONTAL);
		rl_grpGroupsBoard.justify = true;
		grpGroupsBoard.setLayout(rl_grpGroupsBoard);
		grpGroupsBoard.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
		grpGroupsBoard.setText("Groups Board");
		
		tblGroupsBoard = new Table(grpGroupsBoard, SWT.BORDER | SWT.FULL_SELECTION | SWT.HIDE_SELECTION);
		tblGroupsBoard.setLayoutData(new RowData(SWT.DEFAULT, 180));
		tblGroupsBoard.setHeaderVisible(true);
		tblGroupsBoard.setLinesVisible(true);
		final TableColumn tc1 = new TableColumn(tblGroupsBoard, SWT.CENTER);
		tc1.setResizable(false);
		tc1.setText("Group");
	    final TableColumn tc2 = new TableColumn(tblGroupsBoard, SWT.CENTER);
	    tc2.setResizable(false);
	    tc2.setText("Score");
	    tc1.setWidth(150);
    	tc2.setWidth(150);
		
		grpJoinGroup = new Group(usersTabLayout, SWT.NONE);
		RowLayout rl_grpJoinGroup = new RowLayout(SWT.VERTICAL);
		rl_grpJoinGroup.fill = true;
		rl_grpJoinGroup.center = true;
		grpJoinGroup.setLayout(rl_grpJoinGroup);
		GridData gd_grpJoinGroup = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
		gd_grpJoinGroup.widthHint = 230;
		grpJoinGroup.setLayoutData(gd_grpJoinGroup);
		grpJoinGroup.setText("Select Existing Group");
		
		Label lblChooseGroupTo = new Label(grpJoinGroup, SWT.NONE);
		lblChooseGroupTo.setText("Select a group to play with:");
		
		cmbJoinGroup = new Combo(grpJoinGroup, SWT.NONE);
		cmbJoinGroup.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				UserMgmt.populateGroupComboBox();
			}
		});
		
		btnJoinGroup = new Button(grpJoinGroup, SWT.NONE);
		btnJoinGroup.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				joinGroup();
			}
		});
		btnJoinGroup.setText("Select Group");
		
		btnDeleteGroup = new Button(grpJoinGroup, SWT.NONE);
		btnDeleteGroup.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				//like join group but delete it
				int groupIndex;
				if((groupIndex = cmbJoinGroup.getSelectionIndex()) != -1) { // user selected a group
					//delete selected group
					myDB.removeGroup(UserMgmt.groupList.get(groupIndex));
					// show a message
					String selectedGroupName = UserMgmt.groupList.get(groupIndex).getName();
					Logs.append("Group " + selectedGroupName + " deleted.");
					refreshUI();
				};
				
			}
		});
		btnDeleteGroup.setText("Delete Group");
	    
	    // *** Create User ***
		grpNewUser = new Group(usersTabLayout, SWT.NONE);
		grpNewUser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		grpNewUser.setText("Create New User");
		grpNewUser.setLayout(new GridLayout(2, false));
		
		Label lblNewUserName = new Label(grpNewUser, SWT.NONE);
		lblNewUserName.setText("User Name:");
		
		txtNewUserName = new Text(grpNewUser, SWT.BORDER);
		txtNewUserName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		txtNewUserName.setTextLimit(20);
		
		Label lblNewUserPass = new Label(grpNewUser, SWT.NONE);
		lblNewUserPass.setText("Password:");
		
		txtNewUserPass = new Text(grpNewUser, SWT.BORDER | SWT.PASSWORD);
		txtNewUserPass.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		txtNewUserPass.setTextLimit(20);
		
		btnCreateUser = new Button(grpNewUser, SWT.CENTER);
		btnCreateUser.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnCreateUser.setText("Create User");
		btnCreateUser.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				UserMgmt.createNew();
				refreshUI();
			}
		});
		
		grpCreateNewGroup = new Group(usersTabLayout, SWT.NONE);
		grpCreateNewGroup.setLayout(new GridLayout(2, false));
		grpCreateNewGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 3));
		grpCreateNewGroup.setText("Create New Group");
		
		Label lblName = new Label(grpCreateNewGroup, SWT.NONE);
		lblName.setText("Enter Group Name: ");
		
		txtNewGroupName = new Text(grpCreateNewGroup, SWT.BORDER);
		txtNewGroupName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		new Label(grpCreateNewGroup, SWT.NONE);
		new Label(grpCreateNewGroup, SWT.NONE);
		
		Label lblChooseTopics = new Label(grpCreateNewGroup, SWT.NONE);
		lblChooseTopics.setText("Choose Game type:");
		new Label(grpCreateNewGroup, SWT.NONE);
		
		rbtn1ByCountry = new Button(grpCreateNewGroup, SWT.RADIO);
		rbtn1ByCountry.setText("Cities by Country:");
		
		cmbNewGroupCountry = new Combo(grpCreateNewGroup, SWT.NONE);
		cmbNewGroupCountry.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				UserMgmt.populateCountryComboBox();
			}
		});
		cmbNewGroupCountry.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		
		rbtn2ByContinent = new Button(grpCreateNewGroup, SWT.RADIO);
		rbtn2ByContinent.setText("Cities by Continent:");
		
		cmbNewGroupContinent = new Combo(grpCreateNewGroup, SWT.NONE);
		cmbNewGroupContinent.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				UserMgmt.populateContinentComboBox();
			}
		});
		cmbNewGroupContinent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		
		rbtn3AllCities = new Button(grpCreateNewGroup, SWT.RADIO);
		rbtn3AllCities.setSelection(true);
		rbtn3AllCities.setText("All Cities");
		new Label(grpCreateNewGroup, SWT.NONE);
		new Label(grpCreateNewGroup, SWT.NONE);
		new Label(grpCreateNewGroup, SWT.NONE);
		
		Label lblNumberOdQuestions = new Label(grpCreateNewGroup, SWT.NONE);
		lblNumberOdQuestions.setText("Number of questions:");
		
		txtNewGroupQuestions = new Text(grpCreateNewGroup, SWT.BORDER);
		txtNewGroupQuestions.setText("10");
		txtNewGroupQuestions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		new Label(grpCreateNewGroup, SWT.NONE);
		new Label(grpCreateNewGroup, SWT.NONE);
		
		btnCreateGroup = new Button(grpCreateNewGroup, SWT.NONE);
		btnCreateGroup.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				UserMgmt.createNewGroup();
				UserMgmt.populateGroupComboBox();
				cmbJoinGroup.select(cmbJoinGroup.getItemCount() - 1);
				joinGroup();
			}
		});
		btnCreateGroup.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnCreateGroup.setText("Create Group");
		new Label(grpCreateNewGroup, SWT.NONE);
		new Label(grpCreateNewGroup, SWT.NONE);
		
		btnLogout = new Button(usersTabLayout, SWT.NONE);
		btnLogout.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				UserMgmt.logout();
				refreshUI();
			}
		});
		btnLogout.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		btnLogout.setText("Logout");
		new Label(usersTabLayout, SWT.NONE);
		
		btnPlay = new Button(usersTabLayout, SWT.NONE);
		btnPlay.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				tabs.setSelection(tbtmPlay);
			}
		});
		btnPlay.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		btnPlay.setText("Play");
		
		grpGroupInfo = new Group(usersTabLayout, SWT.NONE);
		grpGroupInfo.setLayout(new GridLayout(2, false));
		grpGroupInfo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		grpGroupInfo.setText("Selected Group Info");
		
		lblGroupInfoName = new Label(grpGroupInfo, SWT.NONE);
		lblGroupInfoName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblGroupInfoName.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		lblGroupInfoName.setText("Name:");
		
		txtGroupInfoName = new Text(grpGroupInfo, SWT.BORDER);
		txtGroupInfoName.setEditable(false);
		txtGroupInfoName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		lblGroupInfoType = new Label(grpGroupInfo, SWT.NONE);
		lblGroupInfoType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblGroupInfoType.setText("Type:");
		lblGroupInfoType.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		
		txtGroupInfoType = new Text(grpGroupInfo, SWT.BORDER);
		txtGroupInfoType.setEditable(false);
		txtGroupInfoType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		lblGroupInfoQuestions = new Label(grpGroupInfo, SWT.NONE);
		lblGroupInfoQuestions.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblGroupInfoQuestions.setText("# of questions:");
		lblGroupInfoQuestions.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		
		txtGroupInfoQuestions = new Text(grpGroupInfo, SWT.BORDER);
		txtGroupInfoQuestions.setEditable(false);
		txtGroupInfoQuestions.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		btnLeaveGroup = new Button(grpGroupInfo, SWT.NONE);
		btnLeaveGroup.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (UserMgmt.currUser != null && UserMgmt.currUser.getCurrGroup() != null) {
					myDB.removeUserFromGroup(UserMgmt.currUser, UserMgmt.currUser.getCurrGroup());
					UserMgmt.currUser.setCurrGroup(null);
					txtGroupInfoName.setText("");
					txtGroupInfoType.setText("");
					txtGroupInfoQuestions.setText("");
					refreshUI();
				}
			}
		});
		btnLeaveGroup.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnLeaveGroup.setText("Leave Group");
		
		// *** Play Tab ***
		tbtmPlay = new TabItem(tabs, SWT.NONE);
		tbtmPlay.setText("Play");
		
		Composite playTabLayout = new Composite(tabs, SWT.NONE);
		tbtmPlay.setControl(playTabLayout);
		playTabLayout.setLayout(new GridLayout(2, false));
		
		// *** Google Map ***
		// verify map.html file existence
	    File mapFile = new File("map.html");
	    if(!mapFile.exists()){
	        System.out.println("file not exist! " + mapFile.getAbsolutePath()); 
	        return;
	    }
	    
	    File editMapFile = new File("mapEdit.html");
	    if(!editMapFile.exists()){
	        System.out.println("file not exist! " + editMapFile.getAbsolutePath()); 
	        return;
	    }
		
		Group group = new Group(playTabLayout, SWT.NONE);
		group.setLayout(new GridLayout(1, false));
		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 2));
		
		// *** Generate new Question ***
		btnGenerateQuestion = new Button(group, SWT.NONE);
		btnGenerateQuestion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		btnGenerateQuestion.setSize(220, 50);
		btnGenerateQuestion.setText("Generate New Question");
		
		// *** StopWatch ***
		lblCountdown = new Label(group, SWT.NONE);
		lblCountdown.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		lblCountdown.setSize(220, 50);
		lblCountdown.setAlignment(SWT.CENTER);
		lblCountdown.setFont(SWTResourceManager.getFont("Segoe UI", 24, SWT.NORMAL));
		lblCountdown.setText("--");
		
		// *** Pin It! ***
		btnPinIt = new Button(group, SWT.NONE);
		GridData gd_btnPinIt = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
		gd_btnPinIt.exclude = true;
		btnPinIt.setLayoutData(gd_btnPinIt);
		btnPinIt.setText("Pin It!");
		
		Group grpPlayGroup = new Group(group, SWT.NONE);
		grpPlayGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		grpPlayGroup.setText("Group");
		grpPlayGroup.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		lblPlayGroup = new Label(grpPlayGroup, SWT.NONE);
		lblPlayGroup.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		lblPlayGroup.setAlignment(SWT.CENTER);
		
		grpPlayCurrScore = new Group(group, SWT.NONE);
		grpPlayCurrScore.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
		grpPlayCurrScore.setText("Score");
		grpPlayCurrScore.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		lblPlayCurrScore = new Label(grpPlayCurrScore, SWT.NONE);
		lblPlayCurrScore.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		lblPlayCurrScore.setAlignment(SWT.CENTER);
		
		grpPlayQuestionsLeft = new Group(group, SWT.NONE);
		grpPlayQuestionsLeft.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		grpPlayQuestionsLeft.setText("Questions Left");
		grpPlayQuestionsLeft.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		lblQuestionsLeft = new Label(grpPlayQuestionsLeft, SWT.NONE);
		lblQuestionsLeft.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		lblQuestionsLeft.setAlignment(SWT.CENTER);
		
		tblGrpHighScore = new Table(group, SWT.BORDER | SWT.FULL_SELECTION);
		tblGrpHighScore.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		tblGrpHighScore.setHeaderVisible(true);
		tblGrpHighScore.setLinesVisible(true);
		
		TableColumn tblclmnUser = new TableColumn(tblGrpHighScore, SWT.NONE);
		tblclmnUser.setWidth(80);
		tblclmnUser.setText("User");
		
		TableColumn tblclmnScore = new TableColumn(tblGrpHighScore, SWT.NONE);
		tblclmnScore.setWidth(60);
		tblclmnScore.setText("Score");
		
		btnPinIt.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				PinIt();		    
		    }
		});
		btnGenerateQuestion.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				GenerateNewQuestion();  
			}
		});
		
		// *** Question ***
		Group grpQuestion = new Group(playTabLayout, SWT.NONE);
		GridData gd_grpQuestion = new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1);
		gd_grpQuestion.widthHint = 160;
		grpQuestion.setLayoutData(gd_grpQuestion);
		grpQuestion.setSize(220, 305);
		grpQuestion.setText("Question:");
		FillLayout fl_grpQuestion = new FillLayout(SWT.VERTICAL);
		fl_grpQuestion.marginWidth = 5;
		fl_grpQuestion.marginHeight = 5;
		grpQuestion.setLayout(fl_grpQuestion);
		txtQuestion = new Text(grpQuestion, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.CENTER);
		txtQuestion.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		txtQuestion.setText("See Menu for Instructions.");
		
		browser = new Browser(playTabLayout, SWT.NONE);
		browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		browser.setUrl(mapFile.toURI().toString());
		browser.addControlListener(new ControlListener() {
			public void controlResized(ControlEvent e) {
				browser.execute("document.getElementById('map_canvas').style.width= "+ (browser.getSize().x - 20) + ";");
				browser.execute("document.getElementById('map_canvas').style.height= "+ (browser.getSize().y - 20) + ";");
			}
			
			public void controlMoved(ControlEvent e) {
				// it just has to be here to avoid compilation error.
			}
		});
		
		tbtmStatistics = new TabItem(tabs, SWT.NONE);
		tbtmStatistics.setText("Statistics");
		
		composite = new Composite(tabs, SWT.NONE);
		tbtmStatistics.setControl(composite);
		composite.setLayout(new GridLayout(1, false));
		
		lblStatisticsUser = new Label(composite, SWT.NONE);
		lblStatisticsUser.setFont(SWTResourceManager.getFont("Segoe UI", 14, SWT.NORMAL));
		lblStatisticsUser.setText("User");
		
		tblStatistics = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION);
		GridData gd_tblStatistics = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_tblStatistics.heightHint = 300;
		tblStatistics.setLayoutData(gd_tblStatistics);
		tblStatistics.setHeaderVisible(true);
		tblStatistics.setLinesVisible(true);
		
		tblclmnWhen = new TableColumn(tblStatistics, SWT.NONE);
		tblclmnWhen.setWidth(150);
		tblclmnWhen.setText("When");
		
		tblclmnAskedAbout = new TableColumn(tblStatistics, SWT.NONE);
		tblclmnAskedAbout.setWidth(150);
		tblclmnAskedAbout.setText("Asked about");
		
		tblclmnInGroup = new TableColumn(tblStatistics, SWT.NONE);
		tblclmnInGroup.setWidth(150);
		tblclmnInGroup.setText("In Group");
		
		tblclmnTime = new TableColumn(tblStatistics, SWT.CENTER);
		tblclmnTime.setWidth(100);
		tblclmnTime.setText("Time");
		
		tblclmnScore_1 = new TableColumn(tblStatistics, SWT.CENTER);
		tblclmnScore_1.setWidth(100);
		tblclmnScore_1.setText("Score");
		
		btnUpdateStatistics = new Button(composite, SWT.NONE);
		btnUpdateStatistics.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				UserMgmt.updateStatisticsTable();
			}
		});
		btnUpdateStatistics.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
		btnUpdateStatistics.setText("Update Statistics");
		
		// *** Edit Tab ***
		TabItem tbtmEdit = new TabItem(tabs, SWT.NONE);
		tbtmEdit.setText("Edit");
		
		editTabLayout = new Composite(tabs, SWT.NONE);
		tbtmEdit.setControl(editTabLayout);
		editTabLayout.setLayout(new GridLayout(2, false));
		
		grpEditNew = new Group(editTabLayout, SWT.NONE);
		grpEditNew.setLayout(new GridLayout(2, false));
		grpEditNew.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		grpEditNew.setText("Add New City");
		
		lblName_1 = new Label(grpEditNew, SWT.NONE);
		lblName_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblName_1.setText("Name:");
		
		txtAddCityName = new Text(grpEditNew, SWT.BORDER);
		txtAddCityName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		txtAddCityName.setTextLimit(20);
		
		lblCountry = new Label(grpEditNew, SWT.NONE);
		lblCountry.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblCountry.setText("Country:");
		
		cmbAddCityCountry = new Combo(grpEditNew, SWT.NONE);
		cmbAddCityCountry.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				UserMgmt.populateCountryComboBox();
			}
		});
		cmbAddCityCountry.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		btnAddCity = new Button(grpEditNew, SWT.NONE);
		btnAddCity.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				addCityBtnHandler();
			}
		});
		btnAddCity.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnAddCity.setText("Add City");
		
		grpEditEdit = new Group(editTabLayout, SWT.NONE);
		grpEditEdit.setLayout(new GridLayout(3, false));
		grpEditEdit.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
		grpEditEdit.setText("Edit Existing City");
		
		lblYouCanEdit = new Label(grpEditEdit, SWT.WRAP);
		lblYouCanEdit.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
		lblYouCanEdit.setText("Note you must be logged-in to edit cities coordinates\r\nand you can edit only cities you have been asked about.");
		
		lblSelectCity = new Label(grpEditEdit, SWT.NONE);
		lblSelectCity.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblSelectCity.setText("Select city:");
		
		cmbEditCity = new Combo(grpEditEdit, SWT.NONE);
		cmbEditCity.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				UserMgmt.userQuestions = myDB.getQuestionsByUser(UserMgmt.currUser.getID());
				//populate list only if different in size from userQuestions list
				if (cmbEditCity.getItemCount() != UserMgmt.userQuestions.size()) {
					//clear first
					cmbEditCity.removeAll();
					for (QuestionLog q : UserMgmt.userQuestions) {
						cmbEditCity.add(myDB.getCity(q.getCityId()).getCityName());
					}
				}
			}
		});
		cmbEditCity.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		btnWhereIsIt = new Button(grpEditEdit, SWT.NONE);
		btnWhereIsIt.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				
				//get cityID
				int editCityID = -1;
				int editCitySelectionIdx = -1;
				if((editCitySelectionIdx = cmbEditCity.getSelectionIndex()) != -1) {	
					editCityID = UserMgmt.userQuestions.get(editCitySelectionIdx).getCityId();
				}
				
				//get the city
				City editCity = myDB.getCity(editCityID);
				
				//get city coordinates
				float editCityLat = editCity.getLatitude();
				float editCityLng = editCity.getLongtitude();
				
				//set trueMarker with city coordinates on map
				browserEdit.evaluate("trueLatlng = new google.maps.LatLng(" + editCityLat + ", " + editCityLng + ")");
				browserEdit.evaluate("return placeTrueMarker(trueLatlng)");
				
			}
		});
		btnWhereIsIt.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
		btnWhereIsIt.setText("Where Is It?");
		
		btnEditCity = new Button(grpEditEdit, SWT.NONE);
		btnEditCity.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				editCityBtnHandler();
			}
		});
		btnEditCity.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 3, 1));
		btnEditCity.setText("Change Coordinates");
		
		browserEdit = new Browser(editTabLayout, SWT.NONE);
		browserEdit.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		browserEdit.setUrl(editMapFile.toURI().toString());
		
		tbtmUpdateDb = new TabItem(tabs, SWT.NONE);
		tbtmUpdateDb.setText("Update DB");
		
		updateTabLayout = new Composite(tabs, SWT.NONE);
		tbtmUpdateDb.setControl(updateTabLayout);
		updateTabLayout.setLayout(new GridLayout(1, false));
		
		group_1 = new Group(updateTabLayout, SWT.NONE);
		group_1.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));
		group_1.setText("Update DB");
		group_1.setLayout(new GridLayout(2, false));
		
		lblWarning = new Label(group_1, SWT.NONE);
		lblWarning.setFont(SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		GridData gd_lblWarning = new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1);
		gd_lblWarning.widthHint = 241;
		lblWarning.setLayoutData(gd_lblWarning);
		lblWarning.setText("WARNING! Proceed at your own risk.");
		lblWarning.setAlignment(SWT.CENTER);
		new Label(group_1, SWT.NONE);
		new Label(group_1, SWT.NONE);
		
		lblContinentsCountries = new Label(group_1, SWT.NONE);
		lblContinentsCountries.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblContinentsCountries.setText("Continents and Countries file path:");
		
		txtContinentsPath = new Text(group_1, SWT.BORDER);
		txtContinentsPath.setText("C:\\aFolder\\bFolder\\GeoLite2-Country-Locations.csv");
		GridData gd_txtContinentsPath = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_txtContinentsPath.widthHint = 400;
		txtContinentsPath.setLayoutData(gd_txtContinentsPath);
		
		lblCitiesFilePath = new Label(group_1, SWT.NONE);
		lblCitiesFilePath.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblCitiesFilePath.setText("Cities file path:");
		
		txtCitiesPath = new Text(group_1, SWT.BORDER);
		txtCitiesPath.setText("C:\\aFolder\\bFolder\\worldcitiespop.txt");
		GridData gd_txtCitiesPath = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_txtCitiesPath.widthHint = 400;
		txtCitiesPath.setLayoutData(gd_txtCitiesPath);
		
		lblPinItFolder = new Label(group_1, SWT.NONE);
		lblPinItFolder.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblPinItFolder.setText("Pin It! folder path (without trailing slash):");
		
		txtWorkingFolder = new Text(group_1, SWT.BORDER);
		txtWorkingFolder.setText("C:\\aFolder\\bFolder");
		GridData gd_txtWorkingFolder = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_txtWorkingFolder.widthHint = 400;
		txtWorkingFolder.setLayoutData(gd_txtWorkingFolder);
		new Label(group_1, SWT.NONE);
		new Label(group_1, SWT.NONE);
		
		btnOverride = new Button(group_1, SWT.CHECK);
		btnOverride.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnOverride.setText("Override Cities Coordinates Changed By User");
		new Label(group_1, SWT.NONE);
		new Label(group_1, SWT.NONE);
		
		btnUpdateDB = new Button(group_1, SWT.NONE);
		btnUpdateDB.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				String continentsPath = txtContinentsPath.getText();
				String citiesPath = txtCitiesPath.getText();
				boolean override = btnOverride.getSelection();
				String workingFolder = txtWorkingFolder.getText();
				DB_SQL.updateDB(myDB, continentsPath, citiesPath, override, workingFolder);
			}
		});
		btnUpdateDB.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1));
		btnUpdateDB.setText("Update DB");
		browserEdit.addControlListener(new ControlListener() {
			public void controlResized(ControlEvent e) {
				browserEdit.execute("document.getElementById('map_canvas').style.width= "+ (browserEdit.getSize().x - 20) + ";");
				browserEdit.execute("document.getElementById('map_canvas').style.height= "+ (browserEdit.getSize().y - 20) + ";");
			}
			
			public void controlMoved(ControlEvent e) {
				// it just has to be here to avoid compilation error.
			}
		});
		
		// *** Logs ***
		listLogs = new List(sashBase, SWT.BORDER | SWT.V_SCROLL);
		listLogs.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL));
		sashBase.setWeights(new int[] {6, 1});
	}
}
